package top.infopub.mgr.mkt.service.impl;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.infopub.enums.hr.PostGroupEnum;
import top.infopub.enums.mkt.*;
import top.infopub.mgr.cap.dao.LookInfoBeginDao;
import top.infopub.mgr.exception.FlowProcessException;
import top.infopub.mgr.fia.service.IncomeBillService;
import top.infopub.mgr.fia.service.PayBillService;
import top.infopub.mgr.flow.cnst.FlowTemplateEnum;
import top.infopub.mgr.flow.service.*;
import top.infopub.mgr.mkt.dao.*;
import top.infopub.mgr.mkt.jsonvo.CollectJsonVo;
import top.infopub.mgr.mkt.service.*;
import top.infopub.mgr.mkt.vo.BaseLineVo;
import top.infopub.mgr.om.dao.PaymentApplyDao;
import top.infopub.mgr.sys.service.OperatorService;
import top.infopub.model.flow.Process;
import top.infopub.model.flow.ProcessNode;
import top.infopub.model.flow.Template;
import top.infopub.model.flow.TemplateNode;
import top.infopub.model.mkt.*;
import top.infopub.model.om.PaymentApply;
import top.infopub.model.sys.Operator;
import top.infopub.security.util.SessionUserUtils;
import top.infopub.security.vo.AuthorizationVO;
import top.infopub.tdp.util.BizParaUtil;
import top.infopub.util.IdFactory;
import top.infopub.util.UtilTools;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ProProcessManageServiceImpl implements ProProcessManageService {
    @Autowired
    private ProProcessDetailDao proProcessDetailDao;

    @Lazy
    @Autowired
    private WsFlowProcessService wsFlowProcess;

    @Autowired
    private ProcessService processService;

    @Autowired
    private TemplateService templateService;

    @Autowired
    private TemplateNodeService templateNodeService;

    @Autowired
    private ProcessNodeService processNodeService;

    @Autowired
    private ProjectInfoDao projectInfoDao;

    @Autowired
    private PreProjectDao preProjectDao;

    @Autowired
    private SetupProDao setupProDao;

    @Autowired
    private AfterSummaryCoopDao afterSummaryCoopDao;

    @Autowired
    private ProSellDao proSellDao;

    @Autowired
    private InquiryProDao inquiryProDao;

    @Autowired
    private BidAnalysisDao bidAnalysisDao;

    @Autowired
    private BidBondApplyDao bidBondApplyDao;

    @Autowired
    private BidPlanDao bidPlanDao;

    @Autowired
    private BidDecisionDao bidDecisionDao;

    @Autowired
    private BidInfoDao bidInfoDao;

    @Autowired
    private BidReviewDao bidReviewDao;

    @Autowired
    private BidOpenResultDao bidOpenResultDao;

    @Autowired
    private AfterSummaryDao afterSummaryDao;

    @Autowired
    private DiscloseProDao discloseProDao;

    @Autowired
    private BidSubsidyDao bidSubsidyDao;

    @Autowired
    private MarketingRewardDao marketingRewardDao;

    @Lazy
    @Autowired
    private WsFlowProcessService wsFlowProcessService;

    @Autowired
    private OperatorService operatorService;

    @Autowired
    private BaseLineService baseLineService;

    @Lazy
    @Autowired
    private CollectProjectService collectProjectService;

    @Lazy
    @Autowired
    private OAFlowService oaFlowService;

    @Lazy
    @Autowired
    private ProTrackService proTrackService;

    @Autowired
    private PaymentApplyDao paymentApplyDao;

    @Autowired
    private ProjectRiskService projectRiskService;

    @Autowired
    private LookInfoBeginDao lookInfoBeginDao;

    @Autowired
    private BidBondRecycleDao bidBondRecycleDao;

    @Lazy
    @Autowired
    private IncomeBillService incomeBillService;

    @Lazy
    @Autowired
    private PayBillService payBillService;

    private static String PROJECT_INFO_TABLE = "MKT_COLLECT_PROJECT";

    @Override
    @Transactional
    public String sendProcess(ProProcessDetailTypeEnum ppdt, String detailJson, String bizSguid, String proCode, AuthorizationVO vo) {
        ProjectInfo proInfo = projectInfoDao.findByProCode(proCode);
        if (proInfo == null) {
            throw new FlowProcessException("项目基础数据不存在~~");
        }
        String processId = IdFactory.getUUIDUpper();
        //保存当前详细数据json格式
        ProProcessDetail ppd = new ProProcessDetail();
        ppd.setBizSguid(bizSguid);
        ppd.setProCode(proCode);
        ppd.setProFlowType(ppdt.getType());
        ppd.setProFlowNode(ppdt.getNode());
        ppd.setProcessStatus("1");
        ppd.setDetailJson(detailJson);
        ppd.setAddBy(vo.getId());
        ppd.setAddTime(new Date());
        ppd.setProcessId(processId);
        proProcessDetailDao.insert(ppd);
        //待办标题
        StringBuffer oaTitle = new StringBuffer();
        oaTitle.append(proInfo.getProName());
        oaTitle.append("-");
        oaTitle.append(ppdt.getNodeName());
        // 注意 这里根据不同的业务分支判断条件 获得不同enum
        FlowTemplateEnum templateEnum = getByProProcessNode(ppdt);
        //根据表名更新对应业务表的流程ID和流程状态
        proProcessDetailDao.modifyProcessStatusBySguid(templateEnum.getSrcBizTable(), ProProcesssStatusEnum.PRO_STATUS1.getCode(), processId, bizSguid);
        // 处理工作流数据
        wsFlowProcess.launch(templateEnum, bizSguid, processId, oaTitle.toString());
        return processId;
    }

    private FlowTemplateEnum getByProProcessNode(ProProcessDetailTypeEnum ppdt) {
        if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE.getNode())) {
            //终止项目跟踪
            return FlowTemplateEnum.MKT_COLL_PROJECT_END;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE0.getNode())) {
            //跟踪流程--项目信息收集提交
            return FlowTemplateEnum.MKT_COLLECT_PROJECT;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode())) {
            //跟踪流程--项目跟踪
            return FlowTemplateEnum.MKT_PRO_TRACK;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE1.getNode())) {
            //预立项--项目信息收集跟踪流程通过，判断满足底线标准走预立项流程
            return FlowTemplateEnum.MKT_PRE_PROJECT;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE2.getNode())) {
            //立项--预立项流程通过到立项
            return FlowTemplateEnum.MKT_SETUP_PRO;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE3.getNode())) {
            //营销策划--立项流程通过后可进行营销策划流程
            return FlowTemplateEnum.MKT_PRO_SELL;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE4.getNode())) {
            //资格预审--立项流程通过后可进行资格预审流程
            return FlowTemplateEnum.MKT_INQUIRY_PRO;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE21.getNode())) {
            //资格预审--未通过资审流程
            return FlowTemplateEnum.MKT_INQUIRY_PRO_NO;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE5.getNode())) {
            //招标文件分析--资格预审中选择资格预审流程通过后进入招标文件分析
            return FlowTemplateEnum.MKT_BID_ANALYSIS;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE6.getNode())) {
            //标书策划--招标文件分析流程通过后进入标书策划
            return FlowTemplateEnum.MKT_BID_PLAN;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE7.getNode())) {
            //投标决策--标书策划流程通过后进入投标决策(该地方表名已修改)
            return FlowTemplateEnum.MKT_DECI_PRO;
        }  else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE22.getNode())) {
            //投标决策--是否投标决策选择否-流程
            return FlowTemplateEnum.MKT_DECI_PRO_NO;
        }else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE8.getNode())) {
            //投标保证金--标书策划流程通过后进入投标决策或资格预审中选择资格后审通过后进入投标保证金
            return FlowTemplateEnum.MKT_BID_BOND_APPLY;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE14.getNode())) {
            //回收投标保证金--回收方式为其它
            return FlowTemplateEnum.MKT_BID_BOND_RECYCLE_QT;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE17.getNode())) {
            //回收投标保证金--回收方式为现金
            return FlowTemplateEnum.MKT_BID_BOND_RECYCLE_XJ;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE20.getNode())) {
            //回收投标保证金--财务信息审批(现金方式回收，营销经理填写后发送流程，流程通过后发送待办给财务，财务填写财务信息后提交走该流程)
            return FlowTemplateEnum.MKT_BID_BOND_RECYCLE_CW;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE9.getNode())) {
            //标书评审-商务标--投标保证金流程通过后进入标书评审
            return FlowTemplateEnum.MKT_BID_REVIEW_SW;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE15.getNode())) {
            //标书评审-资信标--投标保证金流程通过后进入标书评审
            return FlowTemplateEnum.MKT_BID_REVIEW_ZX;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE16.getNode())) {
            //标书评审-技术标--投标保证金流程通过后进入标书评审
            return FlowTemplateEnum.MKT_BID_REVIEW_JS;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE10.getNode())) {
            //开标结果--标书评审流程通过后，等待投标截止时间结束，发起开标待办进入开标结果
            return FlowTemplateEnum.MKT_BID_OPEN_RESULT;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE11.getNode())) {
            //标后总结--开标结果流程通过后进入标后总结，未中标标后总结后结束
            return FlowTemplateEnum.MKT_AFTER_SUMMARY;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE12.getNode())) {
            //项目交底--开标结果流程通过后，已中标可进入项目交底
            return FlowTemplateEnum.MKT_DISCLOSE_PRO;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE13.getNode())) {
            //投标补贴--项目交底流程通过后进入投标补贴
            return FlowTemplateEnum.MKT_BID_SUBSIDY;
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE19.getNode())) {
            //营销奖励申请
            return FlowTemplateEnum.MKT_SALE_REWARD;
        }
        return null;
    }

    @Override
    @Transactional
    public void auditProject(String bizSguid, String processId, String status, String auditMsg, String isTrack) {
        Process proc = processService.selectByPrimaryKey(processId);
        if (proc == null) {
            throw new FlowProcessException("获取不到对应的审批主数据~~");
        }
        ProProcessDetail ppd = proProcessDetailDao.queryByProcessId(processId);
        if (ppd == null) {
            throw new FlowProcessException("发起审批业务数据不存在~~");
        }
        bizSguid = ppd.getBizSguid();
        ProjectInfo proInfo = projectInfoDao.findByProCode(ppd.getProCode());
        if (proInfo == null) {
            throw new FlowProcessException("项目基础数据不存在~~");
        }
        // 当前索引
        Integer nowIdx = proc.getNowIdx();
        // 模板ID
        String templateId = proc.getTemplateId();
        // 获得关联业务表名
        String srcBizTable = proc.getSrcBizTable();
        AuthorizationVO vo = SessionUserUtils.getSessionAttributeForUserDtl();
        // 操作人ID
        String userId = vo.getId();
        // 操作人姓名
        String realName = vo.getRealName();
        //待办标题
        StringBuffer oaTitle = new StringBuffer();
        oaTitle.append(proInfo.getProName());
        oaTitle.append("-");
        ProProcessDetailTypeEnum ppdt = ProProcessDetailTypeEnum.getByNode(ppd.getProFlowNode());
        if (ppdt != null) {
            oaTitle.append(ppdt.getNodeName());
        }

        Template queryTemplate = new Template();
        queryTemplate.setId(templateId);
        queryTemplate.setIsUsable("1");// 可用
        List<Template> templates = templateService.selectByEntityWhere(queryTemplate);
        if (templates == null || templates.size() < 1) {
            throw new FlowProcessException("获取不到对应的工作流模板数据~");
        }
        // 查询当前模板剩余的【审批】节点信息 nodex>nowIdx 按照节点索引正序 (不查询[知会]节点)
        List<TemplateNode> templateNodeList = templateNodeService.queryRestNodes(templateId,nowIdx);
        if (templateNodeList == null) {
            throw new FlowProcessException("获取不到对应的工作流节点数据~");
        }

        // 【重要】特殊处理，融资-立项的 副总有最终审批权， [轮到副总审批时]，移除最后的董事长node，使副总作为最后节点
        TemplateNode capSetupFinLast = new TemplateNode();
        if (srcBizTable.equalsIgnoreCase("CAP_SETUP_FIN")) {
            String triggerNodeIdx = BizParaUtil.get("flow_cap_setup_fin_trigger");
            Integer triggerNodeIdxInt = Integer.valueOf(triggerNodeIdx);
            if (nowIdx.equals(triggerNodeIdxInt)) {
                capSetupFinLast = templateNodeList.get(templateNodeList.size() - 1);
                templateNodeList.remove(templateNodeList.size() - 1);
            }
        }

        ProcessNode nowProcNode = new ProcessNode();
        // 非最后一步审核
        if (templateNodeList.size() > 0) {
            // 查询当前审批流程节点
            ProcessNode procNodeWhere = new ProcessNode();
            procNodeWhere.setProcessId(processId);
            procNodeWhere.setNodeIdx(nowIdx);
            procNodeWhere.setState("-1"); // 未审批
            procNodeWhere.setDealUserId(userId);// 审批人为当前操作人
            List<ProcessNode> queryProcessNodes = processNodeService.selectByEntityWhere(procNodeWhere);
            if (queryProcessNodes == null || queryProcessNodes.size() < 1) {
                throw new FlowProcessException("获取不到有效的审批节点数据~");
            }
            // 处理当前审批节点数据
            nowProcNode = queryProcessNodes.get(0);

            //OA待办处理
            if(StringUtils.isNotEmpty(nowProcNode.getOaId())){
                String oaId = nowProcNode.getOaId();
                boolean finishOA = oaFlowService.finishOA(oaId);
                if(finishOA){
                    nowProcNode.setOaFinish(0);
                }else{
//                    throw new FlowProcessException("处理OA待办失败，请联系管理员");
                }
            }

            nowProcNode.setDealName(realName);
            nowProcNode.setDealTime(new Date());
            nowProcNode.setState(status);
            nowProcNode.setDealIdea(auditMsg);
            nowProcNode.setUserOrgId(String.valueOf(SessionUserUtils.getSessionAttribute("bindOrgId")));
            nowProcNode.setUserOrgName(String.valueOf(SessionUserUtils.getSessionAttribute("bindOrgName")));
            nowProcNode.setUserDeptId(String.valueOf(SessionUserUtils.getSessionAttribute("bindDeptId")));
            nowProcNode.setUserDeptName(String.valueOf(SessionUserUtils.getSessionAttribute("bindDeptName")));
            processNodeService.updateByPrimaryKey(nowProcNode);

            //如果是会签，则查询会签是否全部通过
            boolean huiQianFlag = true;
            List<ProcessNode> huiQianProcessNodes = null;
            if(nowProcNode.getNodePolicy() == 3){
                ProcessNode hqNode = new ProcessNode();
                hqNode.setProcessId(processId);
                hqNode.setNodeIdx(nowIdx);
                huiQianProcessNodes = processNodeService.selectByEntityWhere(hqNode);
                for (ProcessNode huiQianProcessNode : huiQianProcessNodes) {
                    if(!"1".equals(huiQianProcessNode.getState())){
                        huiQianFlag = false;
                        break;
                    }
                }
            }

            //审批通过
            if (StringUtils.equals("1", status)) {
                if(huiQianFlag) {
                    //如果是项目信息收集流程或项目跟踪流程，需要把是否跟踪标识更新到项目基础信息表
                    if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE0.getNode(), ppd.getProFlowNode())
                            || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode(), ppd.getProFlowNode())) {
                        proProcessDetailDao.modifyProInfoIsTrack(isTrack, ppd.getProCode());
                    }
                    //判断下个节点是否为--处理中间的知会节点
                    notifyProcess(templateId, nowIdx, processId, srcBizTable, bizSguid);
                    // 下一步的模板节点
                    TemplateNode nextNode = templateNodeList.get(0);
                    List<TemplateNode> nextTemplateNode = new ArrayList<>();
                    for (TemplateNode node : templateNodeList) {
                        if (nextNode.getNodeIdx() == node.getNodeIdx()) {
                            nextTemplateNode.add(node);
                        }
                    }
                    for (TemplateNode templateNode : nextTemplateNode) {
                        List<String> checkUserIds = wsFlowProcessService.checkUserIds(templateNode.getId(), processId);
                        //String tempCheckUserId = checkUserIds(templateNode.getId());
                        for (String tempCheckUserId : checkUserIds) {
                            //发起OA待办
                            String oaId = oaFlowService.sendOAToDo(oaTitle.toString(), SessionUserUtils.getSessionUserId(), tempCheckUserId, srcBizTable, bizSguid);

                            ProcessNode node_next = new ProcessNode();
                            node_next.setAddTime(new Date());
                            node_next.setProcessId(processId);
                            node_next.setNodeIdx(templateNode.getNodeIdx());
                            node_next.setNodeName(templateNode.getNodeName());
                            node_next.setNodePolicy(templateNode.getNodePolicy());// 权限 审批
                            node_next.setDealUserId(tempCheckUserId);// 处理人取模板中的审核人
                            node_next.setDealName(dealNameOf(tempCheckUserId).getSrealName());// 增加处理人姓名
                            node_next.setState("-1");// 节点的审批状态为初始-待审批
                            node_next.setSrcBizTable(srcBizTable);
                            node_next.setSrcBizSguid(bizSguid);
                            node_next.setOaId(oaId);
                            processNodeService.insert(node_next);
                            // 更新审批流程信息
                            proc.setNowIdx(templateNode.getNodeIdx());
                            proc.setMaxIdx(templateNodeList.get(templateNodeList.size() - 1).getNodeIdx());// 再次更新最大索引
                            processService.updateByPrimaryKey(proc);
                        }
                    }
                }
            } else {
                //审批不通过
                proc.setEndTime(new Date());
                proc.setProcessStatus(ProProcesssStatusEnum.PRO_STATUS10.getCode()); // 10=审批终止
                proc.setIsFeedback("0");
                processService.updateByPrimaryKey(proc);
                //如果是预立项流程--删除预立项数据+修改项目信息收集表状态
                if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE1.getNode(), ppd.getProFlowNode())) {
                    //删除预立项数据
                    preProjectDao.deleteByPrimaryKey(bizSguid);
                } else {
                    // 原业务表审批状态 修改为审批终止
                    proProcessDetailDao.modifyProcessStatusBySguid(srcBizTable, ProProcesssStatusEnum.PRO_STATUS10.getCode(), null, bizSguid);
                }
                //修改项目流程明细表状态
                proProcessDetailDao.modifyProcessStatus(ProProcesssStatusEnum.PRO_STATUS10.getCode(), processId);
                //审批不通过需要撤销所有还未审批的会签节点待办
                if (huiQianProcessNodes != null && huiQianProcessNodes.size() > 0) {
                    for (ProcessNode huiQianProcessNode : huiQianProcessNodes) {
                        if("-1".equals(huiQianProcessNode.getState())){
                            oaFlowService.finishOA(huiQianProcessNode.getOaId());
                        }
                    }
                }
            }
        } else {
            //最后一步审核节点
            // 查询当前审批流程节点
            ProcessNode procNodeWhere = new ProcessNode();
            procNodeWhere.setProcessId(processId);
            procNodeWhere.setNodeIdx(nowIdx);
            procNodeWhere.setState("-1"); // 未审批
            procNodeWhere.setDealUserId(userId);// 审批人为当前操作人
            List<ProcessNode> queryProcessNodes = processNodeService.selectByEntityWhere(procNodeWhere);
            if (queryProcessNodes == null || queryProcessNodes.size() < 1) {
                throw new FlowProcessException("获取不到对应的审批节点数据~");
            }
            // 处理当前审批节点数据
            nowProcNode = queryProcessNodes.get(0);

            //OA待办处理
            if(StringUtils.isNotEmpty(nowProcNode.getOaId())){
                String oaId = nowProcNode.getOaId();
                boolean finishOA = oaFlowService.finishOA(oaId);
                if(finishOA){
                    nowProcNode.setOaFinish(0);
                }else{
//                    throw new FlowProcessException("处理OA待办失败，请联系管理员");
                }
            }

            nowProcNode.setDealName(realName);
            nowProcNode.setDealTime(new Date());
            nowProcNode.setState(status);
            nowProcNode.setDealIdea(auditMsg);
            nowProcNode.setUserOrgId(String.valueOf(SessionUserUtils.getSessionAttribute("bindOrgId")));
            nowProcNode.setUserOrgName(String.valueOf(SessionUserUtils.getSessionAttribute("bindOrgName")));
            nowProcNode.setUserDeptId(String.valueOf(SessionUserUtils.getSessionAttribute("bindDeptId")));
            nowProcNode.setUserDeptName(String.valueOf(SessionUserUtils.getSessionAttribute("bindDeptName")));
            processNodeService.updateByPrimaryKey(nowProcNode);

            //如果是会签，则查询会签是否全部通过
            boolean huiQianFlag = true;
            List<ProcessNode> huiQianProcessNodes = null;
            if(nowProcNode.getNodePolicy() == 3){
                ProcessNode hqNode = new ProcessNode();
                hqNode.setProcessId(processId);
                hqNode.setNodeIdx(nowIdx);
                huiQianProcessNodes = processNodeService.selectByEntityWhere(hqNode);
                for (ProcessNode huiQianProcessNode : huiQianProcessNodes) {
                    if(!"1".equals(huiQianProcessNode.getState())){
                        huiQianFlag = false;
                        break;
                    }
                }
            }

            //审核通过
            if (StringUtils.equals("1", status)) {
                // 更新审批流程信息
                if (huiQianFlag) {
                    proc.setEndTime(new Date());
                    proc.setProcessStatus(ProProcesssStatusEnum.PRO_STATUS9.getCode()); // 9=审批完成
                    proc.setIsFeedback("0");
                    processService.updateByPrimaryKey(proc);
                    //如果是项目终止流程，查询立项表获取流程Id，把待办流程结束掉-待开发
                    //如果是项目信息收集流程或项目跟踪流程，需要把是否跟踪标识更新到项目基础信息表
                    if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE0.getNode(), ppd.getProFlowNode())
                            || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode(), ppd.getProFlowNode())) {
                        proProcessDetailDao.modifyProInfoIsTrack(isTrack, ppd.getProCode());
                    }
                    // 原业务表审批状态 修改审批状态
                    proProcessDetailDao.modifyProcessStatusBySguid(srcBizTable, ProProcesssStatusEnum.PRO_STATUS9.getCode(), null, bizSguid);
                    //修改项目流程明细表状态
                    proProcessDetailDao.modifyProcessStatus(ProProcesssStatusEnum.PRO_STATUS9.getCode(), processId);

                    // 所有【审核】节点都通过时， 最后统一生成 后续的【知会】节点
                    List<TemplateNode> toNotifyList = templateNodeService.queryRestNotifyNodes(templateId, nowIdx);
                    for (TemplateNode var : toNotifyList) {
                        List<String> strings = wsFlowProcessService.checkUserIds(var.getId(), processId);
                        for (String string : strings) {
                            ProcessNode node_next = new ProcessNode();
                            node_next.setDealUserId(string);// 处理人取模板中的审核人
                            node_next.setAddTime(new Date());
                            node_next.setProcessId(processId);
                            node_next.setNodeIdx(var.getNodeIdx());
                            node_next.setNodeName(var.getNodeName());
                            node_next.setNodePolicy(2);// 权限 知会
                            node_next.setState("1");// 节点的审批状态为-我已同意
                            node_next.setSrcBizTable(srcBizTable);
                            node_next.setSrcBizSguid(bizSguid);
                            processNodeService.insert(node_next);
                        }
                    }

                    //市场管理-新增下一个业务表数据
                    autoNextBizTableData(ppd, vo, bizSguid, proInfo, isTrack, srcBizTable);
                }
            } else {
                proc.setEndTime(new Date());
                proc.setProcessStatus(ProProcesssStatusEnum.PRO_STATUS10.getCode()); // 10=审批终止
                proc.setIsFeedback("0");
                processService.updateByPrimaryKey(proc);
                //如果是预立项流程--删除预立项数据+修改项目信息收集表状态
                if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE1.getNode(), ppd.getProFlowNode())) {
                    //删除预立项数据
                    preProjectDao.deleteByPrimaryKey(bizSguid);
                }
                // 原业务表审批状态 修改为审批终止
                proProcessDetailDao.modifyProcessStatusBySguid(srcBizTable, ProProcesssStatusEnum.PRO_STATUS10.getCode(), null, bizSguid);
                //修改项目流程明细表状态
                proProcessDetailDao.modifyProcessStatus(ProProcesssStatusEnum.PRO_STATUS10.getCode(), processId);

                //审批不通过需要撤销所有还未审批的会签节点待办
                if (huiQianProcessNodes != null && huiQianProcessNodes.size() > 0) {
                    for (ProcessNode huiQianProcessNode : huiQianProcessNodes) {
                        if("-1".equals(huiQianProcessNode.getState())){
                            oaFlowService.finishOA(huiQianProcessNode.getOaId());
                        }
                    }
                }

                // 【重要】特殊处理，融资-立项的 副总审批拒绝，但是董事长可以继续审批  开始
                if (srcBizTable.equalsIgnoreCase("CAP_SETUP_FIN")) {
                    String triggerNodeIdx = BizParaUtil.get("flow_cap_setup_fin_trigger");
                    if (org.apache.commons.lang.StringUtils.isNotBlank(triggerNodeIdx)) {
                        if (org.apache.commons.lang.StringUtils.equals(nowProcNode.getNodeIdx().toString(), triggerNodeIdx)) {
                            // 董事长模板节点
                            ProcessNode node_next = new ProcessNode();
                            node_next.setAddTime(new Date());
                            node_next.setProcessId(processId);
                            node_next.setNodeIdx(capSetupFinLast.getNodeIdx());
                            node_next.setNodeName(capSetupFinLast.getNodeName());
                            node_next.setNodePolicy(capSetupFinLast.getNodePolicy());// 董事长-权限
                            String tempCheckUserId = wsFlowProcessService.checkUserId(capSetupFinLast.getId());
                            node_next.setDealUserId(tempCheckUserId);// 处理人取模板中的审核人
                            node_next.setDealName(dealNameOf(tempCheckUserId).getSrealName());// 增加处理人姓名
                            node_next.setState("-1");// 节点的审批状态为初始-待审批
                            node_next.setSrcBizTable(srcBizTable);
                            node_next.setSrcBizSguid(bizSguid);
                            processNodeService.insert(node_next);
                            // 更新审批流程信息
                            proc.setNowIdx(capSetupFinLast.getNodeIdx());
                            processService.updateByPrimaryKey(proc);
                        }
                    }
                }// 融资-立项的 副总审批拒绝，但是董事长可以继续审批  结束
            }
        }
    }

    /**
     * 市场管理-审核通过新增下个节点主表数据
     * @param ppd
     * @param vo
     * @param bizSguid
     */
    public void autoNextBizTableData(ProProcessDetail ppd, AuthorizationVO vo, String bizSguid, ProjectInfo proInfo, String isTrack, String srcBizTable) {
        ProProcessDetailTypeEnum ppdt = ProProcessDetailTypeEnum.getByNode(ppd.getProFlowNode());
        if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE0.getNode())
                || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode(), ppd.getProFlowNode())) {
            //获取项目当前阶段
            ProProcessDetailTypeEnum thisPpdt = queryProProcessType(ppd.getProCode());
            //更新风险是否销项
            projectRiskService.updateByid(ppd.getDetailJson());
            if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE0.getNode(), thisPpdt.getNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE1.getNode(), thisPpdt.getNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode(), thisPpdt.getNode())) {
                //判断是否继续跟踪，如果是终止跟踪直接结束
                if (StringUtils.equals("0", isTrack)) {
                    //预立项阶段，判断是否已经存在预立项数据，不存在根据是否满足底线标准发起预立项
                    PreProject prePro = preProjectDao.selectByProCode(ppd.getProCode());
                    if (prePro == null) {
                        //跟踪流程审核通过--判断是否满足底线标准，如果满足发起立项流程
                        List<BaseLineVo> list = baseLineService.checkIsSatisfy(ppd.getProCode());
                        boolean isSend = true;
                        if (list != null && list.size() > 0) {
                            for (BaseLineVo blv : list) {
                                if (!blv.getResult()) {
                                    isSend = false;
                                    break;
                                }
                            }
                        } else {
                            isSend = false;
                        }
                        if (isSend) {
                            CollectProject collPro = collectProjectService.selectByProCodeStatus(ppd.getProCode());
                            CollectJsonVo collectJson = collectProjectService.queryDetailById(collPro.getId());
                            if (collectJson == null) throw new FlowProcessException("获取不到对应的项目信息数据~");
                            PreProject preProject = new PreProject();
                            preProject.setId(IdFactory.getUUIDUpper());
                            preProject.setAddBy(vo.getId());
                            preProject.setAddTime(new Date());
                            preProject.setProCode(ppd.getProCode());
                            preProject.setCodes(IdFactory.getUUIDUpper());
                            preProject.setProcessStatus("1");
                            preProject.setIsMeet("0");
                            preProjectDao.insertById(preProject);
                            sendProcess(ProProcessDetailTypeEnum.PRO_NODE_TYPE1, JSON.toJSONString(collectJson), preProject.getId(), ppd.getProCode(), vo);
                        }
                    }
                }
            } else if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE2.getNode(), thisPpdt.getNode())) {
                //如果是立项阶段，判断是否终止跟踪标识，如果是终止跟踪发起终止流程
                if (StringUtils.equals("1", isTrack)) {
                    CollectJsonVo collectJson = proTrackService.queryDetailById(ppd.getProCode());
                    sendProcess(ProProcessDetailTypeEnum.PRO_NODE_TYPE, JSON.toJSONString(collectJson), collectJson.getProjectInfo().getPreId(), ppd.getProCode(), vo);
                }
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE1.getNode())) {
            //预立项审核通过--往立项主表新增一条记录-底线标准不满足提交发起流程需要填写立项策划信息，往融资初调写入数据
            SetupPro setupPro = new SetupPro();
            setupPro.setCodes(IdFactory.getUUIDUpper());
            setupPro.setProCode(ppd.getProCode());
            setupPro.setAddBy(vo.getId());
            setupPro.setAddTime(new Date());
            setupPro.setProcessStatus("0");
            setupProDao.insertByProcess(setupPro);
            //融资初调
//            LookInfoBegin lookInfoBegin = new LookInfoBegin();
//            lookInfoBegin.setCodes(IdFactory.getUUIDUpper());
//            lookInfoBegin.setProCode(ppd.getProCode());
//            lookInfoBegin.setAddBy(vo.getId());
//            lookInfoBegin.setAddTime(new Date());
//            lookInfoBegin.setUptBy(vo.getId());
//            lookInfoBegin.setUptTime(new Date());
//            lookInfoBeginDao.insertByProcess(lookInfoBegin);
            //给营销经理发送OA待办
            String oaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE2);
            String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_SETUP_PRO.getSrcBizTable(), setupPro.getId());
            if (StringUtils.isNotBlank(oaId)) {
                setupPro.setOaId(oaId);
                setupPro.setUptBy(vo.getId());
                setupPro.setUptTime(new Date());
                setupProDao.modifySetupProById(setupPro);
            }
            //融资初调
//            String libOaTitle = UtilTools.getCapOaTitle(proInfo.getProName(), CapProcessDetailTypeEnum.PRO_NODE_TYPE2);
//            String libOaId = oaFlowService.sendOAToDo(libOaTitle, vo.getId(), vo.getId(), FlowTemplateEnum.CAP_LOOK_INFO_BEGIN.getSrcBizTable(), lookInfoBegin.getId());
//            if (StringUtils.isNotBlank(libOaId)) {
//                proProcessDetailDao.modifyOaIdById(FlowTemplateEnum.CAP_LOOK_INFO_BEGIN.getSrcBizTable(), libOaId, lookInfoBegin.getId());
//            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE2.getNode())) {
            //立项审核通过--往营销策划和资格预审主表写入数据
            //查询业主单位
            List<AfterSummaryCoop> ascList = afterSummaryCoopDao.querySummaryCoopList(ppd.getProCode(), 1);
            //查询立项数据
            SetupPro setupPro = setupProDao.selectByPrimaryKey(bizSguid);
            if (setupPro == null) throw new FlowProcessException("获取不到对应的立项数据~");
            //新增营销策划信息
            ProSell proSell = new ProSell();
            proSell.setCodes(IdFactory.getUUIDUpper());
            proSell.setProCode(ppd.getProCode());
            if (ascList != null && ascList.size() > 0) {
                proSell.setOwnerOrgSguid(ascList.get(0).getSgCoopId());
            }
            if (StringUtils.isNotBlank(setupPro.getGovAccess())) {
                proSell.setInternalReviewStage(setupPro.getGovAccess());
            }
            proSell.setOrgNature(proInfo.getCoopProperty());
            proSell.setInnerRelationship(proInfo.getInnerRelationship());
            proSell.setAddBy(vo.getId());
            proSell.setAddTime(new Date());
            proSell.setUptBy(vo.getId());
            proSell.setUptTime(new Date());
            proSellDao.insertByProcess(proSell);

            //新增资格预审信息
            InquiryPro inquiryPro = new InquiryPro();
            inquiryPro.setCodes(IdFactory.getUUIDUpper());
            inquiryPro.setProCode(ppd.getProCode());
            inquiryPro.setAddBy(vo.getId());
            inquiryPro.setAddTime(new Date());
            inquiryPro.setUptBy(vo.getId());
            inquiryPro.setUptTime(new Date());
            inquiryProDao.insertSelective(inquiryPro);

            //发OA待办给营销经理-营销策划
            String proSellTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE3);
            String oaId = oaFlowService.sendOAToDo(proSellTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_PRO_SELL.getSrcBizTable(), proSell.getId());
            if (StringUtils.isNotBlank(oaId)) {
                proSellDao.modifyOaId(oaId, proSell.getId());
            }

            //发oa待办给营销经理-资格预审
            String inqProTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE4);
            oaId = oaFlowService.sendOAToDo(inqProTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_INQUIRY_PRO.getSrcBizTable(), inquiryPro.getId());
            if (StringUtils.isNotBlank(oaId)) {
                inquiryPro.setOaId(oaId);
                inquiryProDao.updateByIdSelective(inquiryPro);
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE3.getNode())) {
            //营销策划审核通过--暂无操作
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE4.getNode())) {
            //资格预审审批通过--发送待办给营销经理，让营销经理填写是否通过资审，走资审提交-通过资审往招标文件分析写入数据(必须)
            InquiryPro inquiryPro = inquiryProDao.selectByPrimaryKey(bizSguid);
            if (inquiryPro == null) throw new FlowProcessException("资格预审数据不存在~");
            if (StringUtils.equals(InquiryTypeEnum.INQ_TYPE1.getCode(), proInfo.getQualificationType())) {
                //资格后审进入招标文件分析
                BidAnalysis bidAnalysis = new BidAnalysis();
                bidAnalysis.setCodes(IdFactory.getUUIDUpper());
                bidAnalysis.setProCode(ppd.getProCode());
                bidAnalysis.setAddBy(vo.getId());
                bidAnalysis.setAddTime(new Date());
                bidAnalysis.setUptBy(vo.getId());
                bidAnalysis.setUptTime(new Date());
                bidAnalysisDao.insertByProcess(bidAnalysis);
                //给营销经理发送招标文件分析待办
                String oaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE5);
                String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_BID_ANALYSIS.getSrcBizTable(), bidAnalysis.getId());
                if (StringUtils.isNotBlank(oaId)) {
                    bidAnalysis.setOaId(oaId);
                    bidAnalysisDao.modifyById(bidAnalysis);
                }
            } else {
                //发送OA待办--资格预审
                String inqProTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE4);
                String oaId = oaFlowService.sendOAToDo(inqProTitle, vo.getId(), proInfo.getAddBy(), srcBizTable, bizSguid);
                if (StringUtils.isNotBlank(oaId)) {
                    inquiryPro.setOaId(oaId);
                    inquiryProDao.updateByIdSelective(inquiryPro);
                }
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE5.getNode())) {
            //招标文件分析审批通过--往标书策划写入数据，是否需要投标保证金选择是需要往投标保证金申请写入数据
            BidInfo bidInfo = bidInfoDao.queryByProCode(ppd.getProCode());
            if (bidInfo == null) throw new FlowProcessException("投标数据不存在~");
            BidPlan bidPlan = new BidPlan();
            bidPlan.setCodes(IdFactory.getUUIDUpper());
            bidPlan.setProCode(ppd.getProCode());
            bidPlan.setAddBy(vo.getId());
            bidPlan.setAddTime(new Date());
            bidPlan.setUptBy(vo.getId());
            bidPlan.setUptTime(new Date());
            bidPlanDao.insertByProcess(bidPlan);
            //给营销经理发送OA待办-标书策划
            String oaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE6);
            String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_BID_PLAN.getSrcBizTable(), bidPlan.getId());
            if (StringUtils.isNotBlank(oaId)) {
                proProcessDetailDao.modifyOaIdById(FlowTemplateEnum.MKT_BID_PLAN.getSrcBizTable(), oaId, bidPlan.getId());
            }
            //查询资格预审数据
            if (StringUtils.equals(YesOrNoEnum.YES.getCode(), bidInfo.getIsNeedBond())) {
                //需要保证金
                BidBondApply bidBondApply = new BidBondApply();
                bidBondApply.setCodes(IdFactory.getUUIDUpper());
                bidBondApply.setProCode(ppd.getProCode());
                bidBondApply.setBailMethod(bidInfo.getMarginMethod() != null ? bidInfo.getMarginMethod() : "");
                bidBondApply.setReviewMemo("");
                bidBondApply.setAddBy(vo.getId());
                bidBondApply.setAddTime(new Date());
                bidBondApply.setUptBy(vo.getId());
                bidBondApply.setUptTime(new Date());
                bidBondApply.setProcessId("");
                bidBondApply.setProcessStatus("0");
                bidBondApply.setBondType(BidBondApplyTypeEnum.BBA_TYPE2.getCode());
                bidBondApplyDao.insert(bidBondApply);
                //更新Id设置到付款申请主表中
                String applyId = paymentApplyDao.querySguidByProCode(ppd.getProCode(), "2");
                if (StringUtils.isBlank(applyId)) throw  new FlowProcessException("保证金申请信息为空");
                PaymentApply tmpPa = new PaymentApply();
                tmpPa.setId(applyId);
                tmpPa.setBizSguid(bidBondApply.getId());
                paymentApplyDao.updateByIdSelective(tmpPa);
                //给流程中的财务人员发送待办信息
                List<String> finIdList = queryFinanceUserIdByProcessId(ppd.getProcessId(), PostGroupEnum.FINANCE.getCode());
                if (finIdList != null && finIdList.size() > 0) {
                    String bidBondApplyTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE8);
                    String bbaOaId = oaFlowService.sendOAToDo(bidBondApplyTitle, vo.getId(), finIdList.get(0), FlowTemplateEnum.MKT_BID_BOND_APPLY.getSrcBizTable(), bidBondApply.getId());
                    if (StringUtils.isNotBlank(bbaOaId)) {
                        modifyOaIdById(FlowTemplateEnum.MKT_BID_BOND_APPLY.getSrcBizTable(), oaId, bidBondApply.getId());
                    }
                }
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE6.getNode())) {
            //标书策划审批通过--往投标决策写入数据
            BidDecision bidDecision = new BidDecision();
            bidDecision.setCodes(IdFactory.getUUIDUpper());
            bidDecision.setProCode(ppd.getProCode());
            bidDecision.setAddBy(vo.getId());
            bidDecision.setAddTime(new Date());
            bidDecision.setUptBy(vo.getId());
            bidDecision.setUptTime(new Date());
            bidDecisionDao.insertByProcess(bidDecision);
            //给营销经理发送OA待办--投标决策
            String oaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE7);
            String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_DECI_PRO.getSrcBizTable(), bidDecision.getId());
            if (StringUtils.isNotBlank(oaId)) {
                bidDecision.setOaId(oaId);
                bidDecisionDao.modifyById(bidDecision);
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE7.getNode())) {
            //投标决策审批通过--给营销经理发送待办，选择是否投标决策，走投标决策详情，提交根据是否投标决策决定后续
            //是否投标决策，否：项目结束发审批流程，是：往标书评审写入数据继续走流程
            BidDecision bidDecision = bidDecisionDao.queryByProCode(ppd.getProCode());
            if (bidDecision == null) throw new FlowProcessException("获取不到对应的投标决策数据~");
            //发送OA待办--投标决策
            String bidDecTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE7);
            String oaId = oaFlowService.sendOAToDo(bidDecTitle, vo.getId(), proInfo.getAddBy(), srcBizTable, bizSguid);
            if (StringUtils.isNotBlank(oaId)) {
                bidDecision.setOaId(oaId);
                bidDecisionDao.modifyById(bidDecision);
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE8.getNode())) {
            //投标保证金审批通过--财务模块-资金支付-新增主表数据
//            savePayOrIncomeBill(ppd.getProCode(), bizSguid, srcBizTable);
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE9.getNode())) {
            //标书评审-商务标审批通过--往开标结果写入数据，开标结果根据投标截止日期判断是否能编辑中标信息，需要定时任务检测投标截止日期修改开标状态
            BidOpenResult bor = handleBidReview(ppd, vo);
            //给营销经理发送OA待办--开标结果
            if (bor != null) {
                String oaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE10);
                String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_BID_OPEN_RESULT.getSrcBizTable(), bor.getId());
                if (StringUtils.isNotBlank(oaId)) {
                    bor.setOaId(oaId);
                    bor.setUptBy(vo.getId());
                    bor.setUptTime(new Date());
                    bidOpenResultDao.updateById(bor);
                }
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE15.getNode())) {
            //标书评审-资信标审批通过--往开标结果写入数据，开标结果根据投标截止日期判断是否能编辑中标信息，需要定时任务检测投标截止日期修改开标状态
            BidOpenResult bor = handleBidReview(ppd, vo);
            //给营销经理发送OA待办--开标结果
            if (bor != null) {
                String oaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE10);
                String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_BID_OPEN_RESULT.getSrcBizTable(), bor.getId());
                if (StringUtils.isNotBlank(oaId)) {
                    bor.setOaId(oaId);
                    bor.setUptBy(vo.getId());
                    bor.setUptTime(new Date());
                    bidOpenResultDao.updateById(bor);
                }
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE16.getNode())) {
            //标书评审-技术标审批通过--往开标结果写入数据，开标结果根据投标截止日期判断是否能编辑中标信息，需要定时任务检测投标截止日期修改开标状态
            BidOpenResult bor = handleBidReview(ppd, vo);
            //给营销经理发送OA待办--开标结果
            if (bor != null) {
                String oaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE10);
                String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_BID_OPEN_RESULT.getSrcBizTable(), bor.getId());
                if (StringUtils.isNotBlank(oaId)) {
                    bor.setOaId(oaId);
                    bor.setUptBy(vo.getId());
                    bor.setUptTime(new Date());
                    bidOpenResultDao.updateById(bor);
                }
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE10.getNode())) {
            //开标结果审批通过--往标后总结写入数据(必须)，如果中标还需要往项目交底写入数据
            //查询开标结果
            BidOpenResult bor = bidOpenResultDao.queryByProCode(ppd.getProCode());
            if (bor == null) throw new FlowProcessException("获取不到对应的开标结果数据~");

            AfterSummary afterSummary = new AfterSummary();
            afterSummary.setCodes(IdFactory.getUUIDUpper());
            afterSummary.setProCode(ppd.getProCode());
            afterSummary.setAddBy(vo.getId());
            afterSummary.setAddTime(new Date());
            afterSummary.setUptBy(vo.getId());
            afterSummary.setUptTime(new Date());
            afterSummaryDao.insertByProcess(afterSummary);

            //给营销经理发送OA待办--标后总结
            String aftSummOaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE11);
            String oaId = oaFlowService.sendOAToDo(aftSummOaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_AFTER_SUMMARY.getSrcBizTable(), afterSummary.getId());
            if (StringUtils.isNotBlank(oaId)) {
                proProcessDetailDao.modifyOaIdById(FlowTemplateEnum.MKT_AFTER_SUMMARY.getSrcBizTable(), oaId, afterSummary.getId());
            }
            //修改开标结果状态为未中标未总结
            BidOpenResult uptBor = new BidOpenResult();
            uptBor.setId(bor.getId());
            uptBor.setUptBy(vo.getId());
            uptBor.setUptTime(new Date());
            uptBor.setBiddingStatus("4");
            bidOpenResultDao.updateById(uptBor);
            if (StringUtils.equals(YesOrNoEnum.YES.getCode(), bor.getBidding())) {
                //中标
                DisclosePro disclosePro = new DisclosePro();
                disclosePro.setCodes(IdFactory.getUUIDUpper());
                disclosePro.setProCode(ppd.getProCode());
                disclosePro.setAddBy(vo.getId());
                disclosePro.setAddTime(new Date());
                disclosePro.setUptBy(vo.getId());
                disclosePro.setUptTime(new Date());
                discloseProDao.insertByProcess(disclosePro);
                //给营销经理发送OA待办--标后总结
                String disProOaTitle = UtilTools.getMktOaTitle(proInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE12);
                String disProOaId = oaFlowService.sendOAToDo(disProOaTitle, vo.getId(), proInfo.getAddBy(), FlowTemplateEnum.MKT_DISCLOSE_PRO.getSrcBizTable(), disclosePro.getId());
                if (StringUtils.isNotBlank(disProOaId)) {
                    proProcessDetailDao.modifyOaIdById(FlowTemplateEnum.MKT_DISCLOSE_PRO.getSrcBizTable(), disProOaId, disclosePro.getId());
                }
                //中标更新状态已中标未交底
                uptBor.setBiddingStatus("2");
                bidOpenResultDao.updateById(uptBor);
            } else if (StringUtils.equals(YesOrNoEnum.NO.getCode(), bor.getBidding())) {
                //未中标--投标补贴需要手动发起，不发待办
//                BidSubsidy bidSubsidy = new BidSubsidy();
//                bidSubsidy.setCodes(IdFactory.getUUIDUpper());
//                bidSubsidy.setProCode(ppd.getProCode());
//                bidSubsidy.setAddBy(vo.getId());
//                bidSubsidy.setAddTime(new Date());
//                bidSubsidy.setUptBy(vo.getId());
//                bidSubsidy.setUptTime(new Date());
//                bidSubsidyDao.insertByProcess(bidSubsidy);
            } else {
                throw new FlowProcessException("开标结果数据不正确~");
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE11.getNode())) {
            //标后总结审批通过--暂无操作
            //查询开标结果
            BidOpenResult bor = bidOpenResultDao.queryByProCode(ppd.getProCode());
            if (bor == null) throw new FlowProcessException("获取不到对应的开标结果数据~");
            if (StringUtils.equals(YesOrNoEnum.NO.getCode(), bor.getBidding())) {
                //未中标更新状态为未中标已总结
                BidOpenResult uptBor = new BidOpenResult();
                uptBor.setId(bor.getId());
                uptBor.setUptBy(vo.getId());
                uptBor.setUptTime(new Date());
                uptBor.setBiddingStatus("5");
                bidOpenResultDao.updateById(uptBor);
            }
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE12.getNode())) {
            //项目交底审批通过--往营销奖励写入数据，-->进入商务模块(待开发)
            //营销奖励申请手动发起，不发待办
//            DisclosePro disclosePro = discloseProDao.queryByProCode(ppd.getProCode());
//            if (disclosePro == null) throw new FlowProcessException("获取不到对应的项目交底数据~");
//            MarketingReward mktReward = new MarketingReward();
//            mktReward.setCodes(IdFactory.getUUIDUpper());
//            mktReward.setProCode(ppd.getProCode());
//            mktReward.setBondDate(disclosePro.getWidBidDate());
//            mktReward.setAddBy(vo.getId());
//            mktReward.setAddTime(new Date());
//            mktReward.setUptBy(vo.getId());
//            mktReward.setUptTime(new Date());
//            marketingRewardDao.insertByProcess(mktReward);
            //查询开标结果
            BidOpenResult bor = bidOpenResultDao.queryByProCode(ppd.getProCode());
            if (bor == null) throw new FlowProcessException("获取不到对应的开标结果数据~");
            //更新状态为已中标已交底
            BidOpenResult uptBor = new BidOpenResult();
            uptBor.setId(bor.getId());
            uptBor.setUptBy(vo.getId());
            uptBor.setUptTime(new Date());
            uptBor.setBiddingStatus("3");
            bidOpenResultDao.updateById(uptBor);
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE13.getNode())) {
            //投标补贴审批通过--财务模块-资金支付-新增主表数据
//            savePayOrIncomeBill(ppd.getProCode(), bizSguid, srcBizTable);
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE14.getNode())
                || StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE17.getNode())) {
            //回收保证金审批通过--修改保证金申请主表状态
            //财务模块--收款登记-新增主表数据
//            savePayOrIncomeBill(ppd.getProCode(), bizSguid, srcBizTable);
        } else if (StringUtils.equals(ppdt.getNode(), ProProcessDetailTypeEnum.PRO_NODE_TYPE19.getNode())) {
            //营销奖励申请审批通过--财务模块-资金支付-新增主表数据
//            savePayOrIncomeBill(ppd.getProCode(), bizSguid, srcBizTable);
        }
    }

    /**
     * 知会节点处理
     * @param templateId
     * @param thisIdxNo
     * @param processId
     * @param srcBizTable
     * @param srcBizSguid
     * @return
     */
    @Override
    public int notifyProcess(String templateId, Integer thisIdxNo, String processId, String srcBizTable, String srcBizSguid) {
        while (true) {
            //查询下一个节点信息
            int nextNodeIdx = thisIdxNo + 1;
            TemplateNode templateNode = templateNodeService.queryNextIdxsNodes(templateId, nextNodeIdx);
            //如果下个节点为空表示所有节点流程已经走完，返回0
            if (templateNode == null) {
                //修改主表状态为通过
                Process proc = processService.selectByPrimaryKey(processId);
                ProProcessDetail ppd = proProcessDetailDao.queryByProcessId(processId);
                proc.setEndTime(new Date());
                proc.setProcessStatus(ProProcesssStatusEnum.PRO_STATUS9.getCode()); // 9=审批完成
                proc.setIsFeedback("0");
                processService.updateByPrimaryKey(proc);
                //如果是项目终止流程，查询立项表获取流程Id，把待办流程结束掉-待开发
                //如果是项目信息收集流程或项目跟踪流程，需要把是否跟踪标识更新到项目基础信息表
                //项目跟踪或基础信息必须审批，该处代码暂时不需要
//                if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE0.getNode(), ppd.getProFlowNode())
//                        || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode(), ppd.getProFlowNode())) {
//                    proProcessDetailDao.modifyProInfoIsTrack(isTrack, ppd.getProCode());
//                }
                // 原业务表审批状态 修改审批状态
                proProcessDetailDao.modifyProcessStatusBySguid(srcBizTable, ProProcesssStatusEnum.PRO_STATUS9.getCode(), null, srcBizSguid);
                //修改项目流程明细表状态
                proProcessDetailDao.modifyProcessStatus(ProProcesssStatusEnum.PRO_STATUS9.getCode(), processId);

                //支付或付款--需要往财务模块--资金支付/收款登记
//                savePayOrIncomeBill(ppd.getProCode(), srcBizSguid, srcBizTable);
                return 0;
            }
            //如果下个节点不是知会节点返回传入的节点，继续走审批流程
            if (templateNode.getNodePolicy() != 2) return thisIdxNo;
            //知会节点录入默认审核状态为-我已同意
            ProcessNode notify_next = new ProcessNode();
            notify_next.setAddTime(new Date());
            notify_next.setProcessId(processId);
            notify_next.setNodeIdx(templateNode.getNodeIdx());
            notify_next.setNodeName(templateNode.getNodeName());
            notify_next.setNodePolicy(2);// 权限 知会
            notify_next.setDealUserId(wsFlowProcessService.checkUserId(templateNode.getId()));// 处理人取模板中的审核人
            notify_next.setState("1");// 节点的审批状态为-我已同意
            notify_next.setSrcBizTable(srcBizTable);
            notify_next.setSrcBizSguid(srcBizSguid);
            processNodeService.insert(notify_next);
            //记录当前节点
            thisIdxNo = nextNodeIdx;
        }
    }

    /**
     * 查询对应的处理人真实姓名
     */
    private Operator dealNameOf(String checkUserId) {
        Operator opt = operatorService.selectByPrimaryKey(checkUserId);
        if (opt == null) {
            return new Operator();
        }
        else {
            return opt;
        }
    }

    @Override
    public ProProcessDetailTypeEnum queryProProcessType(String proCode) {
        ProProcessDetail ppd = proProcessDetailDao.queryProThisType(proCode);
        if (ppd == null) return ProProcessDetailTypeEnum.PRO_NODE_TYPE0;
        if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode(), ppd.getProFlowNode())) {
            //查询预立项数据
            PreProject prePro = preProjectDao.selectByProCode(proCode);
            if (prePro != null) {
                List<ProProcessDetail> list = proProcessDetailDao.queryByProCode(proCode);
                for (int i = (list.size() - 1); i >= 0; i--) {
                    if (StringUtils.equals(list.get(i).getBizSguid(), prePro.getId())) {
                        ppd = list.get(i);
                        break;
                    }
                }
            }
        }
        //判断当前审批状态，如果是9，获取下一个node的所属type返回，如果不是9直接返回当前node的type
        if (StringUtils.equals(ProProcesssStatusEnum.PRO_STATUS9.getCode(), ppd.getProcessStatus())) {
            if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE18.getNode(), ppd.getProFlowNode())) {
                ppd.setProFlowNode(ProProcessDetailTypeEnum.PRO_NODE_TYPE0.getNode());
            }
            if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE14.getNode(), ppd.getProFlowNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE17.getNode(), ppd.getProFlowNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE20.getNode(), ppd.getProFlowNode())) {
                ppd.setProFlowNode(ProProcessDetailTypeEnum.PRO_NODE_TYPE8.getNode());
            }
            if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE15.getNode(), ppd.getProFlowNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE16.getNode(), ppd.getProFlowNode())) {
                ppd.setProFlowNode(ProProcessDetailTypeEnum.PRO_NODE_TYPE9.getNode());
            }
            Integer nextNode = Integer.valueOf(ppd.getProFlowNode()) + 1;
            //下面流程暂无后续流程，直接返回对应的流程节点
            if (StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE13.getNode(), ppd.getProFlowNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE19.getNode(), ppd.getProFlowNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE21.getNode(), ppd.getProFlowNode())
                    || StringUtils.equals(ProProcessDetailTypeEnum.PRO_NODE_TYPE22.getNode(), ppd.getProFlowNode())) {
                nextNode = Integer.valueOf(ppd.getProFlowNode());
            }
            ProProcessDetailTypeEnum ppdt = ProProcessDetailTypeEnum.getByNode(ppd.getProFlowNode());
            if (ppdt == null) return ProProcessDetailTypeEnum.getByNode(ppd.getProFlowNode());
            return ppdt;
        } else {
            return ProProcessDetailTypeEnum.getByNode(ppd.getProFlowNode());
        }
    }

    /**
     * 标书评审统一处理(包含商务标、资信标、技术标)
     * @param ppd
     * @param vo
     * @return
     */
    public BidOpenResult handleBidReview(ProProcessDetail ppd, AuthorizationVO vo) {
        //标书评审包含三种，存在未审批通过的标书无法走到开标节点
        List<BidReview> list = bidReviewDao.queryByProCode(ppd.getProCode());
        if (list == null || list.size() <= 0) throw new FlowProcessException("获取不到标书评审数据~");
        for (BidReview bidReview : list) {
            if (bidReview == null) continue;
            if (StringUtils.isBlank(bidReview.getProcessStatus())
                    || !StringUtils.equals(ProProcesssStatusEnum.PRO_STATUS9.getCode(), bidReview.getProcessStatus())) {
                return null;
            }
        }
        BidOpenResult bor = new BidOpenResult();
        bor.setCode(IdFactory.getUUIDUpper());
        bor.setProCode(ppd.getProCode());
        bor.setAddBy(vo.getId());
        bor.setAddTime(new Date());
        bor.setUptBy(vo.getId());
        bor.setUptTime(new Date());
        bor.setProcessStatus("0");
        bor.setProcessId("-1");
        bor.setBidding("--");
        bor.setBiddingStatus("0");
        bidOpenResultDao.insertByProcess(bor);
        return bor;
    }

    @Override
    public String checkShowAuditTab(String processId, AuthorizationVO vo) {
        Process proc = processService.selectByPrimaryKey(processId);
        if (proc == null) {
            return "0";
        }
        // 当前索引
        Integer nowIdx = proc.getNowIdx();
        // 查询当前审批流程节点
        ProcessNode procNodeWhere = new ProcessNode();
        procNodeWhere.setProcessId(processId);
        procNodeWhere.setNodeIdx(nowIdx);
        procNodeWhere.setState("-1"); // 未审批
        procNodeWhere.setDealUserId(vo.getId());// 审批人为当前操作人
        List<ProcessNode> queryProcessNodes = processNodeService.selectByEntityWhere(procNodeWhere);
        if (queryProcessNodes == null || queryProcessNodes.size() < 1) {
            return "0";
        }
        return "1";
    }

    @Override
    public String getProCodeById(String tableName, String id) {
        return proProcessDetailDao.queryProCodeById(tableName, id);
    }

    @Override
    public ProProcessDetail queryByProcessId(String processId) {
        return proProcessDetailDao.queryByProcessId(processId);
    }

    @Override
    public List<String> queryFinanceUserIdByProcessId(String processId, String groupId) {
        return proProcessDetailDao.queryFinanceUserIdByProcessId(processId, groupId);
    }

    @Override
    public void modifyOaIdById(String tableName, String oaId, String id) {
        proProcessDetailDao.modifyOaIdById(tableName, oaId, id);
    }

    /**
     * 财务模块，资金支付或收款登记新增数据
     * @param proCode
     * @param bizSguid
     * @param bizTableName
     */
//    public void savePayOrIncomeBill(String proCode, String bizSguid, String bizTableName) {
//        AuthorizationVO vo = SessionUserUtils.getSessionAttributeForUserDtl();
//        if (StringUtils.equals(bizTableName, FlowTemplateEnum.MKT_SALE_REWARD.getSrcBizTable())) {
//            //营销奖励申请
//            MarketingReward saleReward = marketingRewardDao.selectByPrimaryKey(bizSguid);
//            if (saleReward == null) throw new FlowProcessException("营销奖励申请数据不存在~");
//            PayBill payBill = payBillService.setPayBillInfo(proCode, IncomeSettlementModeEnum.INC_SETT_MODE3,
//                    saleReward.getRewardAmount(), saleReward.getRewardAmount(), PayBillTypeEnum.PAY_BILL_TYPE6,
//                    FlowTemplateEnum.MKT_SALE_REWARD, bizSguid, vo);
//            payBillService.insertSelective(payBill);
//        } else if (StringUtils.equals(bizTableName, FlowTemplateEnum.MKT_BID_BOND_RECYCLE_CW.getSrcBizTable())) {
//            //保证金回收
//            BidBondRecycle bidBondRecycle = bidBondRecycleDao.selectByPrimaryKey(bizSguid);
//            if (bidBondRecycle == null) throw new FlowProcessException("保证金回收数据不存在~");
//            IncomeSettlementModeEnum ism = IncomeSettlementModeEnum.INC_SETT_MODE1;
//            if (StringUtils.equals("2", bidBondRecycle.getBailMethodRecycle())) {
//                ism = IncomeSettlementModeEnum.INC_SETT_MODE8;
//            }
//            BigDecimal actualIncAmt = bidBondRecycle.getDepositCollection();
//            if (bidBondRecycle.getActualAmountPayment() != null && bidBondRecycle.getActualAmountPayment().doubleValue() > 0) {
//                actualIncAmt = bidBondRecycle.getActualAmountPayment();
//            }
//            IncomeBill incomeBill = incomeBillService.setIncBillInfo(proCode, ism,
//                    IncomeBillTypeEnum.INCOME_BILL_TYPE1, bidBondRecycle.getDepositCollection(),
//                    actualIncAmt, FlowTemplateEnum.MKT_BID_BOND_RECYCLE_CW, bizSguid, vo);
//            incomeBillService.insertSelective(incomeBill);
//        } else if (StringUtils.equals(bizTableName, FlowTemplateEnum.MKT_BID_SUBSIDY.getSrcBizTable())) {
//            //投标补贴
//            BidSubsidy bidSubsidy = bidSubsidyDao.selectByPrimaryKey(bizSguid);
//            if (bidSubsidy == null) throw new FlowProcessException("投标补贴数据不存在~");
//            PayBill payBill = payBillService.setPayBillInfo(proCode, IncomeSettlementModeEnum.INC_SETT_MODE3,
//                    bidSubsidy.getTotalSum(), bidSubsidy.getTotalSum(), PayBillTypeEnum.PAY_BILL_TYPE5,
//                    FlowTemplateEnum.MKT_BID_SUBSIDY, bizSguid, vo);
//            payBillService.insertSelective(payBill);
//        } else if (StringUtils.equals(bizTableName, FlowTemplateEnum.MKT_BID_BOND_APPLY.getSrcBizTable())) {
//            //保证金
//            BidBondApply bidBondApply = bidBondApplyDao.selectByPrimaryKey(bizSguid);
//            if (bidBondApply == null) throw new FlowProcessException("投标保证金数据不存在~");
//            PaymentApply paymentApply = paymentApplyDao.queryByBizSguid(bizSguid);
//            if (paymentApply == null) throw new FlowProcessException("保证金付款申请数据不存在~");
//            PayBill payBill = payBillService.setPayBillInfo(proCode, IncomeSettlementModeEnum.INC_SETT_MODE3,
//                    paymentApply.getPayTotal(), paymentApply.getPayTotal(), PayBillTypeEnum.PAY_BILL_TYPE1,
//                    FlowTemplateEnum.MKT_BID_BOND_APPLY, bizSguid, vo);
//            payBillService.insertSelective(payBill);
//        }
//    }
}
